<?php


namespace App\Common\Service;

use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Guzzle\CoroutineHandler;
use EasyWeChat\Factory;
use League\Flysystem\FileExistsException;
use Psr\Http\Message\ResponseInterface;

class MiniAppService extends BaseService
{
    /**
     * 小程序
     */
    protected $miniApp;

    /**
     * 公众号
     */
    protected $officialAccount;

    // 指定秒杀商品的提醒
    const SPIKE_ACTIVITY_GOODS_BEGIN = 'OMbt7IoYK2GgLgLpo516iIN9iZqxfZr9wyqXxSQa5GM';
    // 距离最近的秒杀活动提醒
    const SPIKE_CLOSEST_ACTIVITY_BEGIN = 'OMbt7IoYK2GgLgLpo516iPQo6DIXzfr3x9y2ma0vXSU';

    /**
     * 小程序订阅模板id  免单开始  免单失败  免单成功
     */
    const FREE_START = 'LvdduFl2I8r5WhGHRfpywZ4N5zVptoWOEMyL87IRJxI';
    const FREE_SUCCEED = '3TO1vSzXCSyICgI6Kz2mhVu6bkn5f0MixsEAJZKFbOk';
    const FREE_FAIL = 'xqJkZHsMx3xSxN985gSe0CyQRGzrxreMuWIYcZsamcs';

    public function __construct()
    {
        parent::__construct();
        $this->officialAccount = Factory::officialAccount([
            'app_id'        => config('wechat.official_account.app_id'),
            'secret'        => config('wechat.official_account.secret'),
            'response_type' => 'array',
        ]);
        $this->miniApp = Factory::miniProgram([
            'app_id'        => config("wechat.app_id"),
            'secret'        => config("wechat.secret"),
            'response_type' => 'array',
            'log'           => [
                'level' => 'debug',
                'file'  => __DIR__ . '/wechat.log',
            ],
        ]);
    }

    /**
     * 获取小程序码
     *
     * @param $scene
     * @param $params
     * @return string
     * @throws FileExistsException
     */
    public function getMiniAppCodeUrl($scene, $params)
    {
        $handler =new CoroutineHandler();
        // 设置 HttpClient，部分接口直接使用了 http_client。
        $config = $this->miniApp['config']->get('http', []);
        $config['handler'] = $stack = HandlerStack::create($handler);
        $this->miniApp->rebind('http_client', new Client($config));
        $this->miniApp['guzzle_handler'] = $handler;
        $response = $this->miniApp->app_code->getUnlimit($scene, $params);
        if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
            $result = $response->getBody()->getContents();
            $FileName = date("YmdHis") . rand(100, 200) . time() . ".png";
            $this->filesystem->write(env('OSS_DIR') . '/mini/' . $FileName, $result);
            return 'https://' . env('OSS_BUCKET') . '.' . env('OSS_ENDPOINT') . '/' . env('OSS_DIR') . '/mini/' . $FileName;
        }
        return '';
    }

    /**
     * 发送小程序订阅消息
     *
     * @param $open_id
     * @param $template_id
     * @param $page
     * @param $data
     * @return array|Collection|object|ResponseInterface|string
     * @throws InvalidArgumentException
     * @throws InvalidConfigException
     * @throws GuzzleException
     */
    public function sendSubscriptionMessage($open_id, $template_id, $page, $data)
    {
        $_data = [
            'template_id'       => $template_id,
            'touser'            => $open_id,
            'lang'              => 'zh_CN',
            'page'              => $page,
            'miniprogram_state' => config('wechat.miniprogram.state'),
            'data'              => $data,
        ];
        $result = $this->miniApp->subscribe_message->send($_data);
        return [
            'code' => $result['errcode'],
            'msg'  => $result['errmsg'],
        ];
    }
}
